// Handle combotree
App.directive('edCombotree', ['$parse', 'Page', function ($parse, Page) {
    return {

        restrict: 'A',

        // restrict and template attributes are the same as before.
        // we don't need anymore to bind the value to the external ngModel
        // as we require its controller and thus can access it directly
        scope: {
            model: '@ngModel',
            data: '=edData',
            selectable: '&edSelectable'
        },
        // the 'require' property says we need a ngModel attribute in the declaration.
        // this require makes a 4th argument available in the link function below
        require: 'ngModel',

        template: function (elem, attrs) {
            var option = AppUtil.jsonfy(attrs.options);
            var id = Metronic.getUniqueID(), comboOptions = [];
            // 传递给ed-combo的配置
            if (angular.isDefined(option.disabled)) {
                comboOptions.push('disabled:' + option.disabled);
            }
            comboOptions.push("placeholder:'" + (attrs.placeholder || '') + "'");
            if (option.panelWidth) {
                comboOptions.push('panelWidth:' + option.panelWidth);
            }
            return '<div ed-combo="combo_' + id + '" data-options="' + comboOptions.join(',') + '"><ul class="ztree"></ul></div>';
        },

        link: function (scope, elem, attrs, ngModelController) {

            var option = AppUtil.jsonfy(attrs.options);
            // 兼容老的方式
            option.url = option.url || attrs.edUrl;
            option.multiple = option.multiple || (attrs.edMultiple == 'true');
            option.data = option.data || attrs.edData;

            // ztree本身的属性
            option.original = option.original || {};
            if (option.check) {
                option.original.check = option.check;
            }

            if (!option.idField && attrs.edKey) {
                var arr = attrs.edKey.split(',');
                option.parentIdField = arr[0];
                option.idField = arr[1];
                option.textField = arr[2];
            }

            var ztree, combo = scope[$(elem).children('[ed-combo]').attr('id')], ztreeEle = $(elem).find('.ztree:eq(0)');
            ztreeEle.attr('id', Metronic.getUniqueID());// 这里为了避免使用ng-repeat时ztree的id重复

            var setting = {
                check: {
                    enable: true
                },
                view: {
                    selectedMulti: false,
                    fontCss: function(treeId, treeNode) {
                        return (treeNode.highlight == '1') ? {color:"#A60000", "font-weight":"bold"} : {color:"#333", "font-weight":"normal"};
                    }
                },
                data: {
                    simpleData: {
                    },
                    key: {
                    }
                },
                callback: {
                }
            };
            // 自定义ztree的原生配置
            angular.extend(setting, option.original);

            if (option.idField) {
                setting.data.simpleData = {
                    enable: true,
                    idKey: option.idField,
                    pIdKey: option.parentIdField
                };
                setting.data.key = {
                    name: option.textField
                };
            }

            // 判断是返回id还是json
            scope.needJsonValue = true;
            var modelName = AppUtil.getModelName(attrs.ngModel);
            // 如果model的名称和id或父id相同，则值绑定id，否则绑定item
            if (modelName == setting.data.simpleData.idKey || modelName == setting.data.simpleData.pIdKey) {
                scope.needJsonValue = false;
            }
            if (!option.multiple) {// 单选
                setting.check.enable = false;
                setting.callback.onClick = function(event, treeId, treeNode, clickFlag) {
                    scope.$apply(function() {
                        if (typeof scope.selectable === 'function') {// 判断是否可选择
                            if (scope.selectable({data: Ztree.getData(treeNode)}) === false) {
                                if (treeNode.isParent) {// 不可点击时，如果存在子节点，则展开
                                    ztree.expandNode(treeNode);
                                }
                                return;
                            }
                        }
                        scope.setValue(treeNode);
                        combo.hide();
                    });
                };
            } else {// 多选
                setting.check.enable = true;
                setting.callback.onCheck = function(event, treeId, treeNode) {
                    scope.$apply(function(){
                        var checkedNodes = ztree.getCheckedNodes(true);
                        scope.setValue(checkedNodes);
                    });
                };
            }

            if (!angular.isUndefined(attrs.edData)) {// 通过scope指定数据
                scope.$watch('data', function(newValue, oldValue) {
                    if (newValue) {
                        scope.setDataCheckable(newValue);// 设置多选时是否可以选择
                        ztree = $.fn.zTree.init(ztreeEle, setting, newValue);
                        // 展开根节点
                        Ztree.expandRoot(ztree);
                        if (typeof ngModelController.$viewValue !== 'undefined' && ngModelController.$viewValue.length > 0) {
                            ngModelController.$render(false);
                        }
                    }
                });
            } else if (!angular.isUndefined(option.url)) {// URL获取数据
                Page.ajaxPost(option.url, null, function(response) {
                    var datas = response.data;
                    if (!angular.isArray(datas) && angular.isArray(datas.rows)) {
                        datas = datas.rows;
                    }
                    scope.setDataCheckable(datas);// 设置多选时是否可以选择

                    ztree = $.fn.zTree.init(ztreeEle, setting, datas);
                    // 展开根节点
                    Ztree.expandRoot(ztree);
                    // 因为这里是异步加载，需要初始化选择树
                    if (typeof ngModelController.$viewValue !== 'undefined') {
                        ngModelController.$render();
                    }
                });
            }
            // 设置多选时是否可以选择
            scope.setDataCheckable = function(datas) {
                if (option.multiple && typeof scope.selectable === 'function') {// 多选
                    $(datas).each(function(i, data) {
                        data.chkDisabled = scope.selectable({data: data}) === false;
                    });
                }
            }
            scope.search = function() {
                Ztree.search(ztree, option.textField, combo.searchName, function(node) {
                    if (!option.multiple) {// 单选
                        if (typeof scope.selectable === 'function') {// 判断是否可选择
                            if (scope.selectable({data: Ztree.getData(node)}) === false) {
                                return false;
                            }
                        }
                    }
                    return true;
                });
            }
            // 给ng-model赋值
            scope.setValue = function(valueSet) {
                var ids = [], values = [], names = [];
                if (!angular.isUndefined(valueSet)) {
                    if (option.multiple) {// 多选
                        var len = valueSet.length;
                        for (var i = 0; i < len; i++) {
                            var item = Ztree.getData(valueSet[i]);
                            values.push(item);
                            ids.push(item[setting.data.simpleData.idKey]);
                            names.push(item[setting.data.key.name]);
                        }
                    } else {// 单选
                        var item = Ztree.getData(valueSet);
                        values.push(item);
                        ids.push(item[setting.data.simpleData.idKey]);
                        names.push(valueSet[setting.data.key.name]);
                    }
                    // call $parsers pipeline then update $modelValue
                    if (scope.needJsonValue) {// 需要返回json
                        ngModelController.$setViewValue(option.multiple ? values : values[0]);
                    } else {
                        ngModelController.$setViewValue(ids.join(', '));
                    }
                } else {
                    ngModelController.$setViewValue(null);
                }
                // update the local view
                combo.setText(names.join(', '));
            }

            // when model change, update our view (just update the div content)
            ngModelController.$render = function(isUpdateViewOnly) {
                if (ztree) {// 通过外部controller赋值
                    // 先取消选中
                    Ztree.unCheckAllNodes(ztree);

                    var idKey = setting.data.simpleData.idKey;
                    var modelValue = ngModelController.$viewValue;
                    if (!angular.isUndefined(modelValue) && modelValue && modelValue.length > 0) {
                        if (!option.multiple) {// 单选
                            if (angular.isObject(modelValue) && modelValue[idKey]) {// 赋值为json
                                modelValue = modelValue[idKey];
                            }
                            var node = ztree.getNodeByParam(idKey, modelValue, null);
                            if (node) {
                                ztree.selectNode(node, false);
                                ztree.expandNode(node, true);
                                combo.setText(node[setting.data.key.name]);

                                if (scope.needJsonValue && angular.isString(modelValue)) {// 需要返回json但赋值为id
                                    scope.setValue(node);
                                }
                            } else {
                                combo.setText(modelValue);// 找不到对应的name，则显示值
                            }
                        } else {// 多选
                            var values = modelValue;
                            if (angular.isArray(values)) {// 设置的数组
                                $.each(values, function (index, value) {
                                    var node = ztree.getNodeByParam(idKey, value[idKey], null);
                                    if (node && !node.children) {// 叶子节点，这里只选中叶子节点，其关联的节点会相应选中
                                        ztree.checkNode(node, true, true);
                                    }
                                });
                            } else {// 设置的ids
                                $.each(values.split(','), function (index, value) {
                                    var node = ztree.getNodeByParam(idKey, value.trim(), null);
                                    if (node && !node.children) {// 叶子节点，这里只选中叶子节点，其关联的节点会相应选中
                                        ztree.checkNode(node, true, true);
                                    }
                                });
                            }
                            // 展开所有选中节点 todo 这里没有考虑没有对应的name的
                            var checkedNodes = ztree.getCheckedNodes(true), checkedLen = checkedNodes.length;
                            if (checkedLen > 0) {
                                for (var i = 0; i < checkedLen; i++) {
                                    ztree.expandNode(checkedNodes[i], true);
                                }
                            }
                            if ((scope.needJsonValue && angular.isString(values)) || (!scope.needJsonValue && angular.isArray(values))) {// 设置的值类型和期望的不同
                                scope.setValue(checkedNodes);
                            } else {
                                var names = [];
                                $(checkedNodes).each(function(index, item) {
                                    names.push(item[setting.data.key.name]);
                                });
                                combo.setText(names.length > 0 ? names.join(', ') : '');
                            }
                        }
                    } else {//  清空赋值
                        combo.setText('');
                    }
                }
            };
        }

    };
}]);